home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / sos3-2.lha / src / agg / List_scp.c < prev    next >
C/C++ Source or Header  |  1992-01-23  |  24KB  |  664 lines

  1. #line 1 "/fzi/prost/stone/SOS3-2/src/agg/List.c"
  2. /* --------------------------------------------------------------------------
  3.  * Copyright 1992 by Forschungszentrum Informatik (FZI)
  4.  *
  5.  * You can use and distribute this software under the terms of the licence
  6.  * you should have received along with this program.
  7.  * If not or if you want additional information, write to
  8.  * Forschungszentrum Informatik, "STONE", Haid-und-Neu-Strasse 10-14,
  9.  * D-7500 Karlsruhe 1, Germany.
  10.  * --------------------------------------------------------------------------
  11.  */
  12. // **************************************************************************
  13. // Module List                      03/07/89           Bernhard Schiefer (bs)
  14. //                                                   modified : 24/10/91 (bs)
  15. // **************************************************************************
  16. // implements methods of classes: List, sos_List_node
  17. // **************************************************************************
  18.  
  19. #include "sys.h"
  20. #include "agg_err.h"
  21. #include "trc_agg.h"
  22.  
  23. #include "agg_sos.h"
  24.  
  25. // **************************************************************************
  26. void _sos_Object_List::local_initialize (sos_Object_List list)
  27. // **************************************************************************
  28. {  T_PROC ("sos_Object_List::local_initialize");
  29.    TT (agg_H, T_ENTER);
  30.  
  31.    list.set_first (sos_List_node::make (NO_OBJECT));
  32.    list.set_last (sos_List_node::make (NO_OBJECT));
  33.    list.set_cardinality (0);
  34.  
  35.    TT (agg_H, T_LEAVE);
  36. } // ** local_initialize **
  37.  
  38. // **************************************************************************
  39. void _sos_Object_List::local_finalize (sos_Object_List list)
  40. // **************************************************************************
  41. {  T_PROC ("sos_Object_List::local_finalize");
  42.    TT (agg_H, T_ENTER);
  43.  
  44.    list.clear();
  45.  
  46.    TT (agg_H, T_LEAVE);
  47. } // ** local_finalize **
  48.  
  49. // **************************************************************************
  50. void _sos_Object_List::append (sos_Typed_id &_tpid,sos_Object o)
  51. // **************************************************************************
  52. // append an element
  53. {
  54.    T_PROC ("sos_Object_List::append");
  55.    TT (agg_H, T_ENTER);
  56.  
  57.    sos_List_node cn;
  58.    cn = sos_List_node::create (sos_Object_List::make(_tpid,this).container());
  59.    cn.set_val (o);
  60.  
  61.    if (sos_Object_List::make(_tpid,this).get_first() == NO_OBJECT)          // insert the first node
  62.    {  sos_Object_List::make(_tpid,this).set_first (cn);
  63.       sos_Object_List::make(_tpid,this).set_last  (cn);
  64.       cn.set_succ (sos_List_node::make (NO_OBJECT));
  65.       cn.set_pred (sos_List_node::make (NO_OBJECT));
  66.    }
  67.    else
  68.    {  sos_List_node n = sos_Object_List::make(_tpid,this).get_last();
  69.       n.insert_after (cn); 
  70.       sos_Object_List::make(_tpid,this).set_last (cn);
  71.    }
  72.  
  73.    sos_Object_List::make(_tpid,this).set_cardinality (sos_Object_List::make(_tpid,this).get_cardinality() + 1);
  74.  
  75.    TT (agg_H, T_LEAVE);
  76. } // ** append **
  77.  
  78. // **************************************************************************
  79. void _sos_Object_List::insert (sos_Typed_id &_tpid,Index  position, sos_Object o)
  80. // **************************************************************************
  81. // insert an element at the specified position
  82. // if position 0 is specified insert after the last element
  83. {
  84.    T_PROC ("sos_Object_List::insert");
  85.    TT (agg_H, T_ENTER; TI (position));
  86.  
  87.    err_assert (position >= 0, "sos_Object_List::insert");
  88.  
  89.    if (position > sos_Object_List::make(_tpid,this).get_cardinality())
  90.       position = 0;        // insert after last!
  91.  
  92.    if (position == 0)
  93.       sos_Object_List::make(_tpid,this).append (o);
  94.    else
  95.    {  sos_List_node first_node = sos_Object_List::make(_tpid,this).get_first();
  96.       sos_List_node cn = sos_List_node::create (sos_Object_List::make(_tpid,this).container());
  97.       cn.set_val (o);
  98.       if (first_node == NO_OBJECT)              // insert the first node 
  99.       {  sos_Object_List::make(_tpid,this).set_first (cn);
  100.          sos_Object_List::make(_tpid,this).set_last (cn);
  101.      cn.set_succ (sos_List_node::make (NO_OBJECT));
  102.      cn.set_pred (sos_List_node::make (NO_OBJECT));
  103.       }
  104.       else
  105.       {  sos_List_node n = first_node.succ (position - 1);
  106.          n.insert_before (cn);
  107.          if (position == 1) sos_Object_List::make(_tpid,this).set_first (cn);
  108.       } 
  109.       sos_Object_List::make(_tpid,this).set_cardinality (sos_Object_List::make(_tpid,this).get_cardinality() + 1);
  110.    }
  111.    TT (agg_H, T_LEAVE);
  112.  
  113. } // ** insert **
  114.  
  115. // **************************************************************************
  116. void _sos_Object_List::remove (sos_Typed_id &_tpid,Index  position)
  117. // **************************************************************************
  118. {
  119.    T_PROC ("sos_Object_List::remove");
  120.    TT (agg_H, T_ENTER);
  121.  
  122.    sos_List_node first_node = sos_Object_List::make(_tpid,this).get_first();
  123.    err_assert (first_node != NO_OBJECT, "sos_Object_List::remove");
  124.  
  125.    sos_List_node cn = first_node.succ (position - 1);
  126.    err_assert (cn != NO_OBJECT, "sos_Object_List::remove");
  127.  
  128. #ifdef ATT
  129.    if (cn.operator==(first_node))
  130.       sos_Object_List::make(_tpid,this).set_first (first_node.succ());
  131.    if (cn.operator==(sos_Object_List::make(_tpid,this).get_last()))
  132.       sos_Object_List::make(_tpid,this).set_last (sos_Object_List::make(_tpid,this).get_last().pred());
  133. #else
  134.    if (cn == first_node)
  135.       sos_Object_List::make(_tpid,this).set_first (first_node.succ());
  136.    if (cn == sos_Object_List::make(_tpid,this).get_last())
  137.       sos_Object_List::make(_tpid,this).set_last (sos_Object_List::make(_tpid,this).get_last().pred());
  138. #endif
  139.  
  140.    cn.remove(); 
  141.    sos_Object_List::make(_tpid,this).set_cardinality (sos_Object_List::make(_tpid,this).get_cardinality() - 1);
  142.  
  143.    TT (agg_H, T_LEAVE);
  144.  
  145. } // ** remove **
  146.  
  147. // **************************************************************************
  148. sos_Object _sos_Object_List::get_nth (sos_Typed_id &_tpid,Index pos)
  149. // **************************************************************************
  150. {
  151.    T_PROC ("sos_Object_List::get_nth");
  152.    TT (agg_H, T_ENTER; TI (pos));
  153.     
  154.    sos_List_node cn = sos_Object_List::make(_tpid,this).get_first();
  155.    err_assert (cn != NO_OBJECT, "sos_Object_List::get_nth");
  156.  
  157.    cn = cn.succ (pos - 1);
  158.  
  159.    err_assert (cn != NO_OBJECT, "sos_Object_List::get_nth");
  160.  
  161.    sos_Object o = cn.get_val();
  162.  
  163.    TT (agg_H, T_LEAVE);
  164.    return o;
  165. } // ** get_nth **
  166.  
  167. // **************************************************************************
  168. void _sos_Object_List::set_nth (sos_Typed_id &_tpid,Index pos, sos_Object o)
  169. // **************************************************************************
  170. // the value of the sos_Object at Index position is replaced by o
  171. {
  172.    T_PROC ("sos_Object_List::set_nth");
  173.    TT (agg_H, T_ENTER; TI (pos));
  174.  
  175.    sos_List_node cn = sos_Object_List::make(_tpid,this).get_first();
  176.    err_assert (cn != NO_OBJECT, "sos_Object_List::set_nth");
  177.  
  178.    cn = cn.succ (pos - 1);
  179.    err_assert (cn != NO_OBJECT, "sos_Object_List::set_nth");
  180.  
  181.    cn.set_val (o);
  182.  
  183.    TT (agg_H, T_LEAVE);
  184.  
  185. } // ** set_nth **
  186.  
  187. // **************************************************************************
  188. void _sos_Object_List::__plus_assign (sos_Typed_id &_tpid,sos_Object_List alist)
  189. // **************************************************************************
  190. {
  191.    T_PROC ("sos_Object_List::operator+=");
  192.    TT (agg_H, T_ENTER);
  193.  
  194.    for (sos_List_node cn = alist.get_first();
  195.         (cn != NO_OBJECT);
  196.         (cn = cn.succ()))
  197.       sos_Object_List::make(_tpid,this).append (cn.get_val());
  198.  
  199.    TT (agg_H, T_LEAVE);
  200. } // ** operator+= **
  201.  
  202. // **************************************************************************
  203. Index _sos_Object_List::current_pos (sos_Typed_id &_tpid,sos_Cursor c)
  204. // **************************************************************************
  205. {
  206.    T_PROC ("sos_Object_List::current_pos");
  207.    TT (agg_H, T_ENTER);
  208.  
  209.    Index result = 0;
  210.  
  211.    err_assert (sos_Object_List::make(_tpid,this).is_valid (c), "sos_Object_List::current_pos");
  212.  
  213.    for (sos_List_node cn = sos_List_node::make (c.get_current());
  214.         (cn != NO_OBJECT);
  215.         (cn = cn.pred()))
  216.       result++;
  217.  
  218.    TT (agg_H, T_LEAVE; TI (result));
  219.    return result;
  220. } // ** current_pos **
  221.  
  222. // **************************************************************************
  223. sos_Bool _sos_Object_List::move_cursor (sos_Typed_id &_tpid,sos_Cursor c, Index position)
  224. // **************************************************************************
  225. {
  226.    T_PROC ("sos_Object_List::move_cursor");
  227.    TT (agg_H, T_ENTER; TI (position));
  228.  
  229.    err_assert (c.defined_for (sos_Object_List::make(_tpid,this)), "sos_Object_List::move_cursor");
  230.  
  231.    sos_Bool success = TRUE;
  232.    sos_List_node current = sos_Object_List::make(_tpid,this).get_first();
  233.  
  234.    if (current == NO_OBJECT)
  235.       success = FALSE;
  236.    else
  237.    {  current = current.succ (position - 1);
  238.       if (current != NO_OBJECT)
  239.          c.set_current (current);
  240.       else
  241.      success = FALSE;
  242.    } // else
  243.  
  244.    TT (agg_H, T_LEAVE; TB(success));
  245.    return success;
  246. } // ** move_cursor **
  247.  
  248. // **************************************************************************
  249. void _sos_Object_List::insert_before (sos_Typed_id &_tpid,sos_Cursor c, sos_Object o)
  250. // **************************************************************************
  251. {
  252.    T_PROC ("sos_Object_List::insert_before");
  253.    TT (agg_H, T_ENTER);
  254.  
  255.    err_assert (sos_Object_List::make(_tpid,this).is_valid (c), "sos_Object_List::insert_before");
  256.  
  257.    sos_List_node cn = sos_List_node::create (sos_Object_List::make(_tpid,this).container());
  258.    cn.set_val (o);
  259.    sos_List_node::make (c.get_current()).insert_before (cn);
  260.    sos_Object_List::make(_tpid,this).set_cardinality (sos_Object_List::make(_tpid,this).get_cardinality() + 1);
  261.    if (cn.pred() == NO_OBJECT)
  262.       sos_Object_List::make(_tpid,this).set_first (cn);
  263.  
  264.    TT (agg_H, T_LEAVE);
  265. }
  266.  
  267. // **************************************************************************
  268. void _sos_Object_List::insert_after (sos_Typed_id &_tpid,sos_Cursor c, sos_Object o)
  269. // **************************************************************************
  270. {
  271.    T_PROC ("sos_Object_List::insert_after");
  272.    TT (agg_H, T_ENTER);
  273.  
  274.    err_assert (sos_Object_List::make(_tpid,this).is_valid (c), "sos_Object_List::insert_after");
  275.  
  276.    sos_List_node cn = sos_List_node::create (sos_Object_List::make(_tpid,this).container());
  277.    cn.set_val (o);
  278.    sos_List_node::make (c.get_current()).insert_after (cn);
  279.    sos_Object_List::make(_tpid,this).set_cardinality (sos_Object_List::make(_tpid,this).get_cardinality() + 1);
  280.    if (cn.succ() == NO_OBJECT)
  281.       sos_Object_List::make(_tpid,this).set_last (cn);
  282.  
  283.    TT (agg_H, T_LEAVE);
  284. }
  285.  
  286. // **************************************************************************
  287. void _sos_Object_List::local_assign (sos_Object_List x, sos_Object o)
  288. // **************************************************************************
  289. {
  290.    T_PROC ("sos_Object_List::local_assign");
  291.    TT (agg_H, T_ENTER );
  292.  
  293.    sos_Object_List y = sos_Object_List::make (o);
  294.    x.clear();
  295.    x.operator+= (y);
  296.  
  297.    TT (agg_H, T_LEAVE);
  298. } // ** local_assign **
  299.  
  300. // **************************************************************************
  301. sos_Bool _sos_Object_List::local_equal (sos_Object_List x,
  302.                        sos_Object      o,
  303.                        sos_Eq_kind     eq_kind)
  304. // **************************************************************************
  305. {
  306.    T_PROC ("sos_Object_List::local_equal");
  307.    TT (agg_H, T_ENTER );
  308.  
  309.    sos_Bool result;
  310.  
  311.    if ((eq_kind EQ EQ_STRONG AND NOT o.has_type (x.type())) OR
  312.        (eq_kind EQ EQ_WEAK   AND NOT o.isa     (x.type())))
  313.       result = FALSE;
  314.    else
  315.    {  sos_Object_List y = sos_Object_List::make (o);
  316.       if (x.get_cardinality() != y.get_cardinality())
  317.      result = FALSE;
  318.       else
  319.       {  result = TRUE;
  320.      sos_Bool based_on_equal = x.get_based_on_equal();
  321.      sos_Int  comp = 0;
  322.      agg_iterate_double (x, sos_Object x_e, y, sos_Object y_e, comp)
  323.      {  result = agg_same_entity (x_e, y_e, based_on_equal, eq_kind);
  324.         if (NOT result) break;
  325.      }
  326.      agg_iterate_double_end (x, x_e, y, y_e, comp);
  327.      result = (sos_Bool)(result AND comp == 0);
  328.       }
  329.    }
  330.  
  331.    TT (agg_H, T_LEAVE; TB(result));
  332.  
  333.    return result;
  334. } // ** local_equal **
  335.  
  336. // **************************************************************************
  337. sos_Int _sos_Object_List::local_hash_value (sos_Object_List x)
  338. // **************************************************************************
  339. {
  340.    T_PROC ("sos_Object_List::local_hash_value");
  341.    TT (agg_H, T_ENTER );
  342.  
  343.    sos_Int result;
  344.  
  345.    if (x.is_empty())
  346.       result = 0;
  347.    else
  348.       result = x.get_nth (1).hash_value();
  349.  
  350.    TT (agg_H, T_LEAVE; TB(result));
  351.  
  352.    return result;
  353. } // ** local_hash_value **
  354.  
  355. // **************************************************************************
  356. sos_Object _sos_Object_List::get (sos_Typed_id &_tpid,sos_Cursor c)
  357. // **************************************************************************
  358. {
  359.    T_PROC ("sos_Object_List::get (sos_Cursor)");
  360.    TT (agg_H, T_ENTER);
  361.  
  362.    err_assert (sos_Object_List::make(_tpid,this).is_valid (c), "sos_Object_List::get (sos_Cursor)");
  363.  
  364.    sos_Object o = sos_List_node::make (c.get_current()).get_val();
  365.  
  366.    TT (agg_H, T_LEAVE);
  367.    return o;
  368.  
  369. } // ** get **
  370.  
  371. // **************************************************************************
  372. void _sos_Object_List::set (sos_Typed_id &_tpid,sos_Cursor c, sos_Object o)
  373. // **************************************************************************
  374. {
  375.    T_PROC ("sos_Object_List::set");
  376.    TT (agg_H, T_ENTER);
  377.  
  378.    err_assert (sos_Object_List::make(_tpid,this).is_valid (c), "sos_Object_List::set");
  379.  
  380.    sos_List_node::make (c.get_current()).set_val (o);
  381.  
  382.    TT (agg_H, T_LEAVE);
  383.  
  384. } // ** set **
  385.  
  386. // **************************************************************************
  387. void _sos_Object_List::remove_at (sos_Typed_id &_tpid,sos_Cursor c)
  388. // **************************************************************************
  389. {
  390.    T_PROC ("sos_Object_List::remove_at");
  391.    TT (agg_H, T_ENTER);
  392.  
  393.    err_assert (sos_Object_List::make(_tpid,this).is_valid (c), "sos_Object_List::remove_at");
  394.  
  395.    sos_List_node n = sos_List_node::make (c.get_current());
  396.  
  397. #ifdef ATT
  398.    if (n.operator==(sos_Object_List::make(_tpid,this).get_first()))
  399.       sos_Object_List::make(_tpid,this).set_first (sos_Object_List::make(_tpid,this).get_first().succ());
  400.    if (n.operator==(sos_Object_List::make(_tpid,this).get_last()))
  401.       sos_Object_List::make(_tpid,this).set_last (sos_Object_List::make(_tpid,this).get_last().pred());
  402. #else
  403.    if (n == sos_Object_List::make(_tpid,this).get_first())
  404.       sos_Object_List::make(_tpid,this).set_first (sos_Object_List::make(_tpid,this).get_first().succ());
  405.    if (n == sos_Object_List::make(_tpid,this).get_last())
  406.       sos_Object_List::make(_tpid,this).set_last (sos_Object_List::make(_tpid,this).get_last().pred());
  407. #endif
  408.  
  409.    sos_Object_List::make(_tpid,this).to_succ (c);
  410.    n.remove();
  411.    sos_Object_List::make(_tpid,this).set_cardinality (sos_Object_List::make(_tpid,this).get_cardinality() - 1);
  412.  
  413.    TT (agg_H, T_LEAVE);
  414. } // ** remove_at **
  415.  
  416. // **************************************************************************
  417. sos_Int _sos_Object_List::card (sos_Typed_id &_tpid)
  418. // **************************************************************************
  419. {
  420.    T_PROC ("sos_Object_List::card");
  421.    TT (agg_H, T_ENTER);
  422.  
  423.    sos_Int crd = sos_Object_List::make(_tpid,this).get_cardinality();
  424.  
  425.    TT (agg_H, T_LEAVE);
  426.    return crd;
  427. } // ** card **
  428.  
  429. // **************************************************************************
  430. sos_Cursor _sos_Object_List::open_cursor (sos_Typed_id &_tpid,sos_Container ct)
  431. // **************************************************************************
  432. {
  433.    // creates a new cursor-object and positions it 
  434.    // to the first element
  435.  
  436.    T_PROC ("sos_Object_List::open_cursor");
  437.    TT (agg_H, T_ENTER);
  438.  
  439.    sos_Cursor new_c = sos_Cursor::create (ct, sos_Object_List::make(_tpid,this));
  440.    new_c.set_current (sos_Object_List::make(_tpid,this).get_first());
  441.  
  442.    TT (agg_H, T_LEAVE);
  443.    return new_c;
  444. } // ** open_cursor **
  445.  
  446. // **************************************************************************
  447. void _sos_Object_List::close_cursor (sos_Typed_id &_tpid,sos_Cursor c)
  448. // **************************************************************************
  449. {
  450.    // The result of any operation using sos_Cursor c
  451.    // is undefined after this operation.
  452.  
  453.    T_PROC ("sos_Object_List::close_cursor");
  454.    TT (agg_H, T_ENTER);
  455.  
  456.    err_assert (c.defined_for (sos_Object_List::make(_tpid,this)), "sos_Object_List::close_cursor");
  457.  
  458.    c.destroy();
  459.  
  460.    TT (agg_H, T_LEAVE);
  461. } // ** close_cursor **
  462.  
  463. // **************************************************************************
  464. sos_Cursor _sos_Object_List::duplicate (sos_Typed_id &_tpid,sos_Cursor c)
  465. // **************************************************************************
  466. {
  467.    // creates a new cursor-object for the Aggregate and
  468.    // positions it on the same element as c
  469.  
  470.    T_PROC ("sos_Object_List::duplicate");
  471.    TT (agg_H, T_ENTER);
  472.  
  473.    err_assert (c.defined_for (sos_Object_List::make(_tpid,this)), "sos_Object_List::duplicate");
  474.  
  475.    sos_Cursor new_c = sos_Cursor::create (c.container(), sos_Object_List::make(_tpid,this));
  476.    new_c.set_current (c.get_current());
  477.  
  478.    TT (agg_H, T_LEAVE);
  479.    return new_c;
  480. } // ** duplicate **
  481.  
  482. // **************************************************************************
  483. sos_Bool _sos_Object_List::is_valid (sos_Typed_id &_tpid,sos_Cursor c)
  484. // **************************************************************************
  485. {
  486.    T_PROC ("sos_Object_List::is_valid");
  487.    TT (agg_H, T_ENTER);
  488.  
  489.    err_assert (c.defined_for (sos_Object_List::make(_tpid,this)), "sos_Object_List::is_valid");
  490.  
  491.    sos_Bool valid = (c.get_current() != NO_OBJECT);
  492.  
  493.    TT (agg_H, T_LEAVE; TB(valid));
  494.    return valid;
  495. } // ** is_valid **
  496.  
  497. // **************************************************************************
  498. sos_Bool _sos_Object_List::to_first (sos_Typed_id &_tpid,sos_Cursor c)
  499. // **************************************************************************
  500. {
  501.    T_PROC ("sos_Object_List::to_first");
  502.    TT (agg_H, T_ENTER);
  503.  
  504.    err_assert (c.defined_for (sos_Object_List::make(_tpid,this)), "sos_Object_List::to_first");
  505.  
  506.    sos_List_node first = sos_Object_List::make(_tpid,this).get_first();
  507.    c.set_current (first);
  508.  
  509.    sos_Bool valid = (first != NO_OBJECT);
  510.  
  511.    TT (agg_H, T_LEAVE; TB(valid));
  512.    return valid;
  513. } // ** to_first **
  514.  
  515. // **************************************************************************
  516. sos_Bool _sos_Object_List::to_last (sos_Typed_id &_tpid,sos_Cursor c)
  517. // **************************************************************************
  518. {
  519.    T_PROC ("sos_Object_List::to_last");
  520.    TT (agg_H, T_ENTER);
  521.  
  522.    err_assert (c.defined_for (sos_Object_List::make(_tpid,this)), "sos_Object_List::to_last");
  523.  
  524.    sos_List_node last = sos_Object_List::make(_tpid,this).get_last();
  525.    c.set_current (last);
  526.  
  527.    sos_Bool valid = (last != NO_OBJECT);
  528.  
  529.    TT (agg_H, T_LEAVE; TB(valid));
  530.    return valid;
  531. } // ** to_last **
  532.  
  533. // **************************************************************************
  534. sos_Bool _sos_Object_List::to_succ (sos_Typed_id &_tpid,sos_Cursor c, sos_Int i)
  535. // **************************************************************************
  536. {
  537.    // Move the sos_Cursor to the i-th successing element
  538.    // The function returns FALSE if no such element exists.
  539.  
  540.    T_PROC ("sos_Object_List::to_succ");
  541.    TT (agg_H, T_ENTER; TI (i));
  542.  
  543.    err_assert (sos_Object_List::make(_tpid,this).is_valid (c), "sos_Object_List::to_succ");
  544.  
  545.    sos_List_node succ = (sos_List_node::make (c.get_current())).succ (i);
  546.    c.set_current (succ);
  547.  
  548.    sos_Bool valid = (succ != NO_OBJECT);
  549.  
  550.    TT (agg_H, T_LEAVE; TB(valid));
  551.    return (valid);
  552. } // ** to_succ **
  553.  
  554. // **************************************************************************
  555. sos_Bool _sos_Object_List::to_pred (sos_Typed_id &_tpid,sos_Cursor c, sos_Int i)
  556. // **************************************************************************
  557. {
  558.    // Move the sos_Cursor to the previous i-th element
  559.    // The function returns FALSE if no such element exists.
  560.  
  561.    T_PROC ("sos_Object_List::to_pred");
  562.    TT (agg_H, T_ENTER; TI (i));
  563.  
  564.    err_assert (sos_Object_List::make(_tpid,this).is_valid (c), "sos_Object_List::to_pred");
  565.  
  566.    sos_List_node pred = (sos_List_node::make (c.get_current())).pred (i);
  567.    c.set_current (pred);
  568.  
  569.    sos_Bool valid = (pred != NO_OBJECT);
  570.  
  571.    TT (agg_H, T_LEAVE; TB(valid));
  572.    return (valid);
  573. } // ** to_pred **
  574.  
  575. // ***************************    sos_List_node    **************************
  576.  
  577. // **************************************************************************
  578. void _sos_List_node::insert_before (sos_Typed_id &_tpid,sos_List_node n)
  579. // **************************************************************************
  580. {
  581.    T_PROC ("sos_List_node::insert_before");
  582.    TT (agg_H, T_ENTER);
  583.  
  584.    sos_List_node pred = sos_List_node::make(_tpid,this).get_pred();
  585.  
  586.    n.set_pred (pred);
  587.    n.set_succ (sos_List_node::make(_tpid,this));
  588.    sos_List_node::make(_tpid,this).set_pred (n);
  589.    if (pred != NO_OBJECT) pred.set_succ (n);
  590.  
  591.    TT (agg_H, T_LEAVE);
  592. }  // ** insert_before **
  593.  
  594. // **************************************************************************
  595. void _sos_List_node::insert_after (sos_Typed_id &_tpid,sos_List_node n)
  596. // **************************************************************************
  597. {
  598.    T_PROC ("sos_List_node::insert_after");
  599.    TT (agg_H, T_ENTER);
  600.  
  601.    sos_List_node succ = sos_List_node::make(_tpid,this).get_succ();
  602.  
  603.    n.set_pred (sos_List_node::make(_tpid,this));
  604.    n.set_succ (succ);
  605.    sos_List_node::make(_tpid,this).set_succ (n);
  606.    if (succ != NO_OBJECT) succ.set_pred (n);
  607.  
  608.    TT (agg_H, T_LEAVE);
  609. }  // ** insert_after **
  610.  
  611. // **************************************************************************
  612. void _sos_List_node::remove (sos_Typed_id &_tpid)
  613. // **************************************************************************
  614. {
  615.    T_PROC ("sos_List_node::remove");
  616.    TT (agg_H, T_ENTER);
  617.  
  618.    sos_List_node pred = sos_List_node::make(_tpid,this).get_pred();
  619.    sos_List_node succ = sos_List_node::make(_tpid,this).get_succ();
  620.  
  621.    if (pred != NO_OBJECT) pred.set_succ (succ);
  622.    if (succ != NO_OBJECT) succ.set_pred (pred);
  623.  
  624.    sos_List_node::make(_tpid,this).destroy();      // destroy the node
  625.  
  626.    TT (agg_H, T_LEAVE);
  627. }  // ** remove **
  628.  
  629. // **************************************************************************
  630. sos_List_node _sos_List_node::succ (sos_Typed_id &_tpid,sos_Int steps)
  631. // **************************************************************************
  632. {
  633.    T_PROC ("sos_List_node::succ");
  634.    TT (agg_H, T_ENTER; TI (steps));
  635.  
  636.    sos_List_node node = sos_List_node::make(_tpid,this);
  637.  
  638.    for (sos_Int i = 1;
  639.         (i <= steps) AND (node != NO_OBJECT);
  640.         i++)
  641.        node = node.get_succ ();
  642.  
  643.    TT (agg_H, T_LEAVE; TI(i));
  644.    return node;
  645. }  // ** succ **
  646.  
  647. // **************************************************************************
  648. sos_List_node _sos_List_node::pred (sos_Typed_id &_tpid,sos_Int steps)
  649. // **************************************************************************
  650. {
  651.    T_PROC ("sos_List_node::pred");
  652.    TT (agg_H, T_ENTER; TI (steps));
  653.  
  654.    sos_List_node node = sos_List_node::make(_tpid,this);
  655.  
  656.    for (sos_Int i = 1;
  657.         (i <= steps) AND (node != NO_OBJECT);
  658.         i++)
  659.        node = node.get_pred();
  660.  
  661.    TT (agg_H, T_LEAVE; TI(i));
  662.    return node;
  663. }  // ** pred **
  664.